﻿#region Usings

using System;
using System.Collections.Generic;
using System.Linq;

#endregion

namespace SilverBox.Imaging
{
    public class TransportableBitmap : IDisposable
    {
        public TransportableBitmap()
        {
        }

        public TransportableBitmap(int[] pixels, int pixelHeight, int pixelWidth)
        {
            LoadColors(pixels);

            PixelHeight = pixelHeight;
            PixelWidth = pixelWidth;
        }

        public List<Map> Colors { get; set; }

        public int[] Pixels { get; set; }
        public int PixelHeight { get; set; }
        public int PixelWidth { get; set; }

        #region IDisposable Members

        public void Dispose()
        {
            Map.Clear();
        }

        #endregion

        private void LoadColors(int[] pixels)
        {
            Colors = new List<Map>();
            for (var i = 0; i < pixels.Count(); i++)
            {
                var x = i;
                if (!Map.Exists(pixels[x]))
                {
                    Colors.Add(new Map(pixels[x]));
                }
                var map = Map.Get(pixels[x]);

                if (map.R.Count > 0)
                {
                    var lR = map.R.Last();
                    if (lR.X0 + lR.X == i - 1)
                        lR.X++;
                    else
                        map.R.Add(new Range {X0 = x});
                }
                else
                    map.R.Add(new Range {X0 = x});
            }
        }
    }

    public class Map
    {
        private static readonly Dictionary<int, Map> Maps;

        static Map()
        {
            Maps = new Dictionary<int, Map>();
        }

        public Map()
        {
        }

        public Map(int c)
        {
            Maps.Add(c, this);
            C = c;
            R = new List<Range>();
        }

        public int C { get; set; }
        public List<Range> R { get; set; }

        public static bool Exists(int c)
        {
            return Maps.ContainsKey(c);
        }

        public static Map Get(int c)
        {
            return Exists(c) ? Maps[c] : null;
        }

        public static void Clear()
        {
            Maps.Clear();
        }
    }

    public class Range
    {
        public int X0 { get; set; }
        public int X { get; set; }
    }
}